package tt.dz.order.schedulingjob;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;

import tt.dz.order.pojo.OrderAccountingStatus;
import tt.dz.order.pojo.OrderInfo;
import tt.dz.order.pojo.OrderRefundStatus;
import tt.dz.order.pojo.YouBeiPayCallBackRecord;
import tt.dz.order.pojo.YouBeiRefundReturnRecord;
import tt.dz.order.util.AmountUtil;
import tt.dz.order.util.OrderConstant.OrderPayChannelCode;
import tt.dz.order.util.OrderConstant.OrderStatus;
import tt.dz.order.util.UUIDUtil;
import tt.dz.order.util.YouBeiPayUtil;

/**
 * @Title 向有贝先付平台发送充电预约退款请求的job
 * @author zhoutian   
 * @date 2015-11-17
 */
@Component
public class SendRefundingRequestToYouBeiJob extends QuartzJobBean {
	private static Logger log = LoggerFactory.getLogger(SendRefundingRequestToYouBeiJob.class);
	
	//截取的大小
	private int subSize = 50;
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED, rollbackFor=java.lang.Exception.class)
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		//log.info("向有贝先付平台发送充电预约退款请求,job start");
		List<OrderRefundStatus> list = null;
		try{
			try {
				list = OrderRefundStatus.getRefundInfoForSend(OrderPayChannelCode.youbeipay.value());
			} catch(Exception e){
				return;
			}
			if(list != null && list.size() > 0){
				//截取一部分（50个）充电预约退款订单发送
				List<OrderRefundStatus> subList = null;
				List<String> refundOrderNos = null;
				if(list.size() >= subSize){
					subList = list.subList(0, subSize);
					refundOrderNos = new ArrayList<String>(subSize);
				} else {
					subList = list;
					refundOrderNos = new ArrayList<String>(list.size());
				}
				for(OrderRefundStatus crs : subList){
					refundOrderNos.add(crs.getOrderNo());
				}
				//修改充电预约退款订单的状态为"正在发送"
				OrderRefundStatus.changeStatusToSending(refundOrderNos);
				//找出充电预约退款订单列表
				List<OrderInfo> refundOrderList = OrderInfo.getByIds(refundOrderNos);
				//key为充电预约订单号，value为充电预约退款订单
				Map<String, OrderInfo> refundOrderMap = new HashMap<String, OrderInfo>();
				List<String> chargeAppointmentOrderNos = new ArrayList<String>();
				for(OrderInfo refundOrder : refundOrderList){
					//充电预约退款订单的关联订单为充电预约订单
					String chargeAppointmentOrderNo = refundOrder.getRelatedOrderNo();
					chargeAppointmentOrderNos.add(chargeAppointmentOrderNo);
					refundOrderMap.put(chargeAppointmentOrderNo, refundOrder);
				}
				//找出充电预约订单支付回调记录
				List<YouBeiPayCallBackRecord> youbeiPayCallBackRecords = YouBeiPayCallBackRecord.getByIds(chargeAppointmentOrderNos);
				//要发送的参数
				Map<String, String> paramMap = new TreeMap<String, String>(
						new Comparator<String>(){
							@Override
							public int compare(String key1, String key2) {
								return key1.compareTo(key2);
							}
						}
				);
				List<String> needSendAgainOrderNos = new ArrayList<String>();
				List<String> successOrderNos = new ArrayList<String>();
				for(int i = 0 ; i < youbeiPayCallBackRecords.size(); i++){
					YouBeiPayCallBackRecord youbeiPayCallBackRecord = youbeiPayCallBackRecords.get(i);
					String chargeAppointmentOrderNo = youbeiPayCallBackRecord.getOrderNo();
					OrderInfo refundOrder = refundOrderMap.get(chargeAppointmentOrderNo);
					String refundOrderNo = refundOrder.getOrderNo();
					BigDecimal refundFeeForSend = refundOrder.getCaculatedTotalPrice().abs();
					//商户编号
					paramMap.put("oid_partner", youbeiPayCallBackRecord.getPartnerNo());
					//签名方式
					paramMap.put("sign_type", youbeiPayCallBackRecord.getSignType());
					//商户退款流水号
					paramMap.put("no_refund", refundOrderNo);
					//商户退款时间
					paramMap.put("dt_refund", UUIDUtil.getCurrentDate14(null));
					//退款金额
					paramMap.put("money_refund", refundFeeForSend.toString());
					//原商户订单号
					paramMap.put("no_order", chargeAppointmentOrderNo);
					//原商户订单时间
					paramMap.put("dt_order", youbeiPayCallBackRecord.getGmtPayment());
					//原有贝先付支付单号
					paramMap.put("oid_paybill", youbeiPayCallBackRecord.getTradeNo());
					String sign = YouBeiPayUtil.sign(paramMap);
					paramMap.put("sign", sign);
					String retJsonStr = YouBeiPayUtil.sendRefundRequest(JSON.toJSONString(paramMap));
					if(retJsonStr == null || retJsonStr.trim().length() == 0){
						needSendAgainOrderNos.add(refundOrderNo);
					} else {
						YouBeiRefundReturnRecord youbeiRefundReturnRecord = JSON.parseObject(retJsonStr, YouBeiRefundReturnRecord.class);
						String return_code = youbeiRefundReturnRecord.getRetCode();
						//退款金额
						String refund_fee = (String) youbeiRefundReturnRecord.getRefundFee();
						if(return_code == null || !return_code.equals("0000")){
							log.error("向有贝先付平台发送充电预约退款请求返回失败，refundOrderNo,return_code,result_code:", refundOrderNo + "," + return_code);
							needSendAgainOrderNos.add(refundOrderNo);
						} else if(!AmountUtil.equal(new BigDecimal(refund_fee), refundFeeForSend)){
							log.error("向有贝先付平台发送充电预约退款请求,返回的退款金额与发送的不符，refundOrderNo,refundFeeForSend,returnedRefundFee:", refundOrderNo + "," + refundFeeForSend + "," + refund_fee);
							needSendAgainOrderNos.add(refundOrderNo);
						} else {
							successOrderNos.add(refundOrderNo);
						}
					}
					YouBeiRefundReturnRecord youbeiRefundCallBackRecord = YouBeiRefundReturnRecord.getBy(refundOrderNo);
					//查询订单退款回调记录是否存在
					if(youbeiRefundCallBackRecord == null){
						//新增回调记录
						youbeiRefundCallBackRecord = new YouBeiRefundReturnRecord(paramMap);
						youbeiRefundCallBackRecord.save();
					} else {
						//更新回调记录
						youbeiRefundCallBackRecord = new YouBeiRefundReturnRecord(paramMap);
						youbeiRefundCallBackRecord.update();
					}
				}
				if(needSendAgainOrderNos.size() > 0){
					OrderRefundStatus.changeStatusToNeedSendAgain(needSendAgainOrderNos);
				}
				if(successOrderNos.size() > 0){
					OrderRefundStatus.changeStatusToSuccess(successOrderNos);
					OrderInfo.changeOrderStatus(successOrderNos, OrderStatus.payedDone.value());
					OrderAccountingStatus.batchSave(successOrderNos);
				}
			}
		} catch(Exception e){
			log.error("向有贝先付平台发送充电预约退款请求出错", e);
		}
	}
}
